import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Task } from './task.entity';
import axios from 'axios';
import { RobotService } from '../robot/robot.service';
import { TaskResponse } from './task.dto';
import { TaskRepository } from './task.repository';
import { LogService } from '../log/log.service';
import { CronService } from '../cron/cron.service';

@Injectable()
export class TaskService {
  constructor(
    @InjectRepository(Task)
    private taskRepository: TaskRepository,
    private robotService: RobotService,
    private logService: LogService,
    @Inject(forwardRef(() => CronService))
    private cronService: CronService,
  ) { }

  async findAll(robotId?: number): Promise<TaskResponse[]> {
    const where = robotId ? { robotId } : {};
    try {
      const tasks = await this.taskRepository.find({ where });

      // 确保msgContent永远不会是null
      return tasks.map(task => {
        // 创建一个新对象
        const formattedTask: any = {
          ...task,
          msgContent: task.msgContent || '{}',
          msgType: task.msgType || 'text',
          remark: task.remark || '',
          cronText: task.cronText || '',
        };

        // 格式化日期为字符串
        formattedTask.createDateString = task.createDate
          ? task.createDate.toISOString()
          : new Date().toISOString();

        formattedTask.updateDateString = task.updateDate
          ? task.updateDate.toISOString()
          : new Date().toISOString();

        formattedTask.executeTimeString = task.executeTime
          ? task.executeTime.toISOString()
          : null;

        return formattedTask;
      });
    } catch (error) {
      console.error('Error fetching tasks:', error);
      return []; // 返回空数组而不是抛出错误
    }
  }

  async findOne(id: number): Promise<TaskResponse> {
    const task = await this.taskRepository.findOne({ where: { id } });
    return this.addDateStrings(task);
  }

  async createMessage(createTaskDto: any): Promise<any> {
    const { robotId, msgContent, save, userId } = createTaskDto;

    // 解析msgContent
    let parsedContent;
    try {
      parsedContent = typeof msgContent === 'string' ? JSON.parse(msgContent) : msgContent;
    } catch (e) {
      console.error('解析消息内容失败:', e);
      throw new Error('消息内容格式不正确');
    }

    const content = parsedContent.content;

    if (!content) {
      throw new Error('消息内容不能为空');
    }

    // 查找机器人
    const robot = await this.robotService.findOne(robotId);
    if (!robot) {
      throw new Error('机器人不存在');
    }

    // 发送消息
    try {
      console.log('发送到微信机器人的内容:', content);
      const response = await axios.post(robot.webhook, {
        msgtype: 'text',
        text: {
          content
        }
      });

      // 如果需要保存
      if (save) {
        const task = new Task();
        task.robotId = robotId;
        task.userId = userId;
        task.msgType = 'text';
        task.msgContent = typeof msgContent === 'string' ? msgContent : JSON.stringify(parsedContent);
        task.remark = content.substring(0, 20); // 摘取前20个字符作为备注
        await this.taskRepository.save(task);
      }

      return response.data;
    } catch (error) {
      console.error('发送消息错误详情:', error.response ? error.response.data : error.message);
      throw new Error('发送消息失败: ' + error.message);
    }
  }

  // 辅助方法：添加字符串格式的日期字段
  private addDateStrings(task: Task): TaskResponse {
    if (!task) return null;

    const result = task as any;

    result.createDateString = task.createDate
      ? task.createDate.toISOString()
      : new Date().toISOString();

    result.updateDateString = task.updateDate
      ? task.updateDate.toISOString()
      : new Date().toISOString();

    result.executeTimeString = task.executeTime
      ? task.executeTime.toISOString()
      : null;

    return result;
  }

  async createTask(createTaskDto: any): Promise<Task> {
    const { robotId, msgContent, executeTime, userId } = createTaskDto;

    // 解析msgContent，与createMessage方法保持一致
    let parsedContent;
    try {
      parsedContent = typeof msgContent === 'string' ? JSON.parse(msgContent) : msgContent;
    } catch (e) {
      console.error('解析消息内容失败:', e);
      throw new Error('消息内容格式不正确');
    }

    const content = parsedContent.content;

    if (!content) {
      throw new Error('消息内容不能为空');
    }

    const task = new Task();
    task.robotId = robotId;
    task.userId = userId;
    task.msgType = 'text';
    task.msgContent = typeof msgContent === 'string' ? msgContent : JSON.stringify(parsedContent);
    task.isOneTime = true;  // 设置为一次性任务
    task.executeTime = new Date(executeTime);  // 设置执行时间
    task.remark = content.substring(0, 20); // 摘取前20个字符作为备注

    // 保存任务
    const savedTask = await this.taskRepository.save(task);

    // 如果是一次性任务，创建调度
    if (task.isOneTime && task.status === '1') {
      await this.cronService.createOneTime(savedTask.id, savedTask.executeTime);
    }
    // 如果是周期性任务，创建调度
    else if (!task.isOneTime && task.cron && task.status === '1') {
      await this.cronService.createTask(savedTask.id, task.cron, task.isWorkday);
    }

    return this.addDateStrings(savedTask);
  }

  async updateTask(id: number, updateTaskDto: any): Promise<Task> {
    // 获取更新前的任务信息
    const oldTask = await this.taskRepository.findOne({ where: { id } });

    await this.taskRepository.update(id, updateTaskDto);
    const updatedTask = await this.taskRepository.findOne({ where: { id } });

    // 如果任务状态变为禁用，取消现有调度
    if (oldTask.status === '1' && updatedTask.status !== '1') {
      await this.cronService.cancel(id);
    }
    // 如果任务状态变为启用，创建新调度
    else if (oldTask.status !== '1' && updatedTask.status === '1') {
      if (updatedTask.isOneTime) {
        await this.cronService.createOneTime(id, updatedTask.executeTime);
      } else if (updatedTask.cron) {
        await this.cronService.createTask(id, updatedTask.cron, updatedTask.isWorkday);
      }
    }
    // 如果任务参数变化，更新调度
    else if (updatedTask.status === '1' &&
      (oldTask.cron !== updatedTask.cron ||
        oldTask.isWorkday !== updatedTask.isWorkday ||
        oldTask.isOneTime !== updatedTask.isOneTime ||
        oldTask.executeTime !== updatedTask.executeTime)) {
      // 取消原有调度
      await this.cronService.cancel(id);

      // 创建新调度
      if (updatedTask.isOneTime) {
        await this.cronService.createOneTime(id, updatedTask.executeTime);
      } else if (updatedTask.cron) {
        await this.cronService.createTask(id, updatedTask.cron, updatedTask.isWorkday);
      }
    }

    return this.addDateStrings(updatedTask);
  }

  async removeTask(id: number): Promise<void> {
    // 取消调度
    await this.cronService.cancel(id);

    // 删除任务
    await this.taskRepository.delete(id);
  }

  // 发送任务消息
  async sendTaskMessage(task: Task): Promise<any> {
    try {
      // 解析消息内容
      const parsedContent = JSON.parse(task.msgContent);
      const content = parsedContent.content;

      if (!content) {
        throw new Error('消息内容为空');
      }

      // 查找机器人
      const robot = await this.robotService.findOne(task.robotId);
      if (!robot) {
        throw new Error('机器人不存在');
      }

      // 发送消息到微信
      console.log(`发送任务消息 (ID: ${task.id}) 到微信机器人:`, content);
      const response = await axios.post(robot.webhook, {
        msgtype: 'text',
        text: {
          content
        }
      });

      // 记录日志
      try {
        await this.logService.create({
          robotId: task.robotId,
          taskId: task.id,
          userId: task.userId,
          methond: '1', // 自动发送
          msgType: task.msgType || 'text',
          msgContent: task.msgContent,
          remark: task.remark || content.substring(0, 20) || '无内容',
          status: response.data.errcode === 0 ? '1' : '0' // 根据API返回设置成功/失败
        });
      } catch (err) {
        console.error('保存定时任务日志记录失败:', err);
      }

      return response.data;
    } catch (error) {
      console.error('发送任务消息失败:', error);

      // 记录失败日志
      try {
        await this.logService.create({
          robotId: task.robotId,
          taskId: task.id,
          userId: task.userId,
          methond: '1', // 自动发送
          msgType: task.msgType || 'text',
          msgContent: task.msgContent,
          remark: task.remark || '无内容',
          status: '0' // 失败
        });
      } catch (err) {
        console.error('保存失败日志记录失败:', err);
      }

      throw new Error('发送任务消息失败: ' + error.message);
    }
  }
}